From 4d383b129dd51083a917f5c82ec9f3314c577a65 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Oct 2018 21:09:49 -0700 Subject: [PATCH] ARM: De-macro-ize ARM/Thumb PC write routines --- include/mgba/internal/arm/isa-inlines.h | 30 +++++++++++++------------ src/arm/arm.c | 16 ++++--------- src/arm/debugger/debugger.c | 10 ++++----- src/arm/isa-arm.c | 18 +++++++-------- src/arm/isa-thumb.c | 16 ++++++------- src/debugger/gdb-stub.c | 10 ++++----- src/gba/bios.c | 3 +-- src/gba/gba.c | 3 +-- 8 files changed, 47 insertions(+), 59 deletions(-) diff --git a/include/mgba/internal/arm/isa-inlines.h b/include/mgba/internal/arm/isa-inlines.h index 5850dab69..a73c157b4 100644 --- a/include/mgba/internal/arm/isa-inlines.h +++ b/include/mgba/internal/arm/isa-inlines.h @@ -55,21 +55,23 @@ #define ARM_STUB cpu->irqh.hitStub(cpu, opcode) #define ARM_ILL cpu->irqh.hitIllegal(cpu, opcode) -#define ARM_WRITE_PC \ - cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM); \ - cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ - LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - cpu->gprs[ARM_PC] += WORD_SIZE_ARM; \ - LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - currentCycles += 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32; +static inline int32_t ARMWritePC(struct ARMCore* cpu) { + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM); + cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); + LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + cpu->gprs[ARM_PC] += WORD_SIZE_ARM; + LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + return 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32; +} -#define THUMB_WRITE_PC \ - cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB); \ - cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ - LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; \ - LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - currentCycles += 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16; +static inline int32_t ThumbWritePC(struct ARMCore* cpu) { + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB); + cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); + LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + return 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16; +} static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) { return mode != MODE_SYSTEM && mode != MODE_USER; diff --git a/src/arm/arm.c b/src/arm/arm.c index d0325dc05..bd8c3b565 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -135,9 +135,7 @@ void ARMReset(struct ARMCore* cpu) { cpu->executionMode = MODE_THUMB; _ARMSetMode(cpu, MODE_ARM); - - int currentCycles = 0; - ARM_WRITE_PC; + ARMWritePC(cpu); cpu->cycles = 0; cpu->nextEvent = 0; @@ -161,12 +159,10 @@ void ARMRaiseIRQ(struct ARMCore* cpu) { cpu->cpsr.priv = MODE_IRQ; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; cpu->gprs[ARM_PC] = BASE_IRQ; - int currentCycles = 0; - ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); + cpu->cycles += ARMWritePC(cpu); cpu->spsr = cpsr; cpu->cpsr.i = 1; - cpu->cycles += currentCycles; cpu->halted = 0; } @@ -182,12 +178,10 @@ void ARMRaiseSWI(struct ARMCore* cpu) { cpu->cpsr.priv = MODE_SUPERVISOR; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_SWI; - int currentCycles = 0; - ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); + cpu->cycles += ARMWritePC(cpu); cpu->spsr = cpsr; cpu->cpsr.i = 1; - cpu->cycles += currentCycles; } void ARMRaiseUndefined(struct ARMCore* cpu) { @@ -202,12 +196,10 @@ void ARMRaiseUndefined(struct ARMCore* cpu) { cpu->cpsr.priv = MODE_UNDEFINED; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_UNDEF; - int currentCycles = 0; - ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); + cpu->cycles += ARMWritePC(cpu); cpu->spsr = cpsr; cpu->cpsr.i = 1; - cpu->cycles += currentCycles; } static inline void ARMStep(struct ARMCore* cpu) { diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c index 55105a17d..292b98c87 100644 --- a/src/arm/debugger/debugger.c +++ b/src/arm/debugger/debugger.c @@ -347,11 +347,10 @@ bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32 } if (strcmp(name, "pc") == 0) { cpu->gprs[ARM_PC] = value; - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } return true; } @@ -363,11 +362,10 @@ bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32 } cpu->gprs[reg] = value; if (reg == ARM_PC) { - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } } return true; diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index e9ed19a2d..901174b75 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -253,7 +253,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { #define ADDR_MODE_2_WRITEBACK(ADDR) \ cpu->gprs[rn] = ADDR; \ if (UNLIKELY(rn == ARM_PC)) { \ - ARM_WRITE_PC; \ + currentCycles += ARMWritePC(cpu); \ } #define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I) @@ -278,7 +278,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { #define ARM_LOAD_POST_BODY \ currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; \ if (rd == ARM_PC) { \ - ARM_WRITE_PC; \ + currentCycles += ARMWritePC(cpu); \ } #define ARM_STORE_POST_BODY \ @@ -301,9 +301,9 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { S_BODY; \ if (rd == ARM_PC) { \ if (cpu->executionMode == MODE_ARM) { \ - ARM_WRITE_PC; \ + currentCycles += ARMWritePC(cpu); \ } else { \ - THUMB_WRITE_PC; \ + currentCycles += ThumbWritePC(cpu); \ } \ }) @@ -594,7 +594,7 @@ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, load, currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; if (rs & 0x8000) { - ARM_WRITE_PC; + currentCycles += ARMWritePC(cpu); }) DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM, @@ -625,22 +625,22 @@ DEFINE_INSTRUCTION_ARM(B, int32_t offset = opcode << 8; offset >>= 6; cpu->gprs[ARM_PC] += offset; - ARM_WRITE_PC;) + currentCycles += ARMWritePC(cpu);) DEFINE_INSTRUCTION_ARM(BL, int32_t immediate = (opcode & 0x00FFFFFF) << 8; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - WORD_SIZE_ARM; cpu->gprs[ARM_PC] += immediate >> 6; - ARM_WRITE_PC;) + currentCycles += ARMWritePC(cpu);) DEFINE_INSTRUCTION_ARM(BX, int rm = opcode & 0x0000000F; _ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001); cpu->gprs[ARM_PC] = cpu->gprs[rm] & 0xFFFFFFFE; if (cpu->executionMode == MODE_THUMB) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); } else { - ARM_WRITE_PC; + currentCycles += ARMWritePC(cpu); }) // End branch definitions diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index 54faf6ddc..ad72bffb9 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -238,14 +238,14 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(MVN, cpu->gprs[rd] = ~cpu->gprs[rn]; THUMB_ DEFINE_INSTRUCTION_WITH_HIGH_THUMB(ADD4, cpu->gprs[rd] += cpu->gprs[rm]; if (rd == ARM_PC) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); }) DEFINE_INSTRUCTION_WITH_HIGH_THUMB(CMP3, int32_t aluOut = cpu->gprs[rd] - cpu->gprs[rm]; THUMB_SUBTRACTION_S(cpu->gprs[rd], cpu->gprs[rm], aluOut)) DEFINE_INSTRUCTION_WITH_HIGH_THUMB(MOV3, cpu->gprs[rd] = cpu->gprs[rm]; if (rd == ARM_PC) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); }) #define DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(NAME, BODY) \ @@ -310,7 +310,7 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(STMIA, if (ARM_COND_ ## COND) { \ int8_t immediate = opcode; \ cpu->gprs[ARM_PC] += (int32_t) immediate << 1; \ - THUMB_WRITE_PC; \ + currentCycles += ThumbWritePC(cpu); \ }) DEFINE_CONDITIONAL_BRANCH_THUMB(EQ) @@ -346,7 +346,7 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(POPR, rs |= 1 << ARM_PC, THUMB_LOAD_POST_BODY; cpu->gprs[ARM_SP] = address; - THUMB_WRITE_PC;) + currentCycles += ThumbWritePC(cpu);) DEFINE_LOAD_STORE_MULTIPLE_THUMB(PUSH, ARM_SP, @@ -369,7 +369,7 @@ DEFINE_INSTRUCTION_THUMB(BKPT, cpu->irqh.bkpt16(cpu, opcode & 0xFF);) DEFINE_INSTRUCTION_THUMB(B, int16_t immediate = (opcode & 0x07FF) << 5; cpu->gprs[ARM_PC] += (((int32_t) immediate) >> 4); - THUMB_WRITE_PC;) + currentCycles += ThumbWritePC(cpu);) DEFINE_INSTRUCTION_THUMB(BL1, int16_t immediate = (opcode & 0x07FF) << 5; @@ -380,7 +380,7 @@ DEFINE_INSTRUCTION_THUMB(BL2, uint32_t pc = cpu->gprs[ARM_PC]; cpu->gprs[ARM_PC] = cpu->gprs[ARM_LR] + immediate; cpu->gprs[ARM_LR] = pc - 1; - THUMB_WRITE_PC;) + currentCycles += ThumbWritePC(cpu);) DEFINE_INSTRUCTION_THUMB(BX, int rm = (opcode >> 3) & 0xF; @@ -391,9 +391,9 @@ DEFINE_INSTRUCTION_THUMB(BX, } cpu->gprs[ARM_PC] = (cpu->gprs[rm] & 0xFFFFFFFE) - misalign; if (cpu->executionMode == MODE_THUMB) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); } else { - ARM_WRITE_PC; + currentCycles += ARMWritePC(cpu); }) DEFINE_INSTRUCTION_THUMB(SWI, cpu->irqh.swi16(cpu, opcode & 0xFF)) diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 73dd978d6..f5b5218d5 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -305,11 +305,10 @@ static void _writeGPRs(struct GDBStub* stub, const char* message) { cpu->gprs[r] = _hex2int(readAddress, 8); readAddress += 8; } - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4); @@ -369,11 +368,10 @@ static void _writeRegister(struct GDBStub* stub, const char* message) { if (reg <= ARM_PC) { cpu->gprs[reg] = value; if (reg == ARM_PC) { - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } } } else if (reg == 0x19) { diff --git a/src/gba/bios.c b/src/gba/bios.c index ead5332c2..286c00a7f 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -43,8 +43,7 @@ static void _SoftReset(struct GBA* gba) { cpu->gprs[ARM_PC] = BASE_CART0; } _ARMSetMode(cpu, MODE_ARM); - int currentCycles = 0; - ARM_WRITE_PC; + ARMWritePC(cpu); } static void _RegisterRamReset(struct GBA* gba) { diff --git a/src/gba/gba.c b/src/gba/gba.c index eab779158..0e58f1618 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -242,8 +242,7 @@ void GBASkipBIOS(struct GBA* gba) { } gba->memory.io[REG_VCOUNT >> 1] = 0x7E; gba->memory.io[REG_POSTFLG >> 1] = 1; - int currentCycles = 0; - ARM_WRITE_PC; + ARMWritePC(cpu); } }