ARM: De-macro-ize ARM/Thumb PC write routines

This commit is contained in:
Vicki Pfau 2018-10-12 21:09:49 -07:00
parent 830cad3e7b
commit 4d383b129d
8 changed files with 47 additions and 59 deletions

View File

@ -55,21 +55,23 @@
#define ARM_STUB cpu->irqh.hitStub(cpu, opcode) #define ARM_STUB cpu->irqh.hitStub(cpu, opcode)
#define ARM_ILL cpu->irqh.hitIllegal(cpu, opcode) #define ARM_ILL cpu->irqh.hitIllegal(cpu, opcode)
#define ARM_WRITE_PC \ static inline int32_t ARMWritePC(struct ARMCore* cpu) {
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM); \ cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM);
cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]);
LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion);
cpu->gprs[ARM_PC] += WORD_SIZE_ARM; \ cpu->gprs[ARM_PC] += WORD_SIZE_ARM;
LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion);
currentCycles += 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32; return 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32;
}
#define THUMB_WRITE_PC \ static inline int32_t ThumbWritePC(struct ARMCore* cpu) {
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB); \ cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB);
cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]);
LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion);
cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; \ cpu->gprs[ARM_PC] += WORD_SIZE_THUMB;
LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion);
currentCycles += 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16; return 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16;
}
static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) { static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {
return mode != MODE_SYSTEM && mode != MODE_USER; return mode != MODE_SYSTEM && mode != MODE_USER;

View File

@ -135,9 +135,7 @@ void ARMReset(struct ARMCore* cpu) {
cpu->executionMode = MODE_THUMB; cpu->executionMode = MODE_THUMB;
_ARMSetMode(cpu, MODE_ARM); _ARMSetMode(cpu, MODE_ARM);
ARMWritePC(cpu);
int currentCycles = 0;
ARM_WRITE_PC;
cpu->cycles = 0; cpu->cycles = 0;
cpu->nextEvent = 0; cpu->nextEvent = 0;
@ -161,12 +159,10 @@ void ARMRaiseIRQ(struct ARMCore* cpu) {
cpu->cpsr.priv = MODE_IRQ; cpu->cpsr.priv = MODE_IRQ;
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM;
cpu->gprs[ARM_PC] = BASE_IRQ; cpu->gprs[ARM_PC] = BASE_IRQ;
int currentCycles = 0;
ARM_WRITE_PC;
_ARMSetMode(cpu, MODE_ARM); _ARMSetMode(cpu, MODE_ARM);
cpu->cycles += ARMWritePC(cpu);
cpu->spsr = cpsr; cpu->spsr = cpsr;
cpu->cpsr.i = 1; cpu->cpsr.i = 1;
cpu->cycles += currentCycles;
cpu->halted = 0; cpu->halted = 0;
} }
@ -182,12 +178,10 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
cpu->cpsr.priv = MODE_SUPERVISOR; cpu->cpsr.priv = MODE_SUPERVISOR;
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
cpu->gprs[ARM_PC] = BASE_SWI; cpu->gprs[ARM_PC] = BASE_SWI;
int currentCycles = 0;
ARM_WRITE_PC;
_ARMSetMode(cpu, MODE_ARM); _ARMSetMode(cpu, MODE_ARM);
cpu->cycles += ARMWritePC(cpu);
cpu->spsr = cpsr; cpu->spsr = cpsr;
cpu->cpsr.i = 1; cpu->cpsr.i = 1;
cpu->cycles += currentCycles;
} }
void ARMRaiseUndefined(struct ARMCore* cpu) { void ARMRaiseUndefined(struct ARMCore* cpu) {
@ -202,12 +196,10 @@ void ARMRaiseUndefined(struct ARMCore* cpu) {
cpu->cpsr.priv = MODE_UNDEFINED; cpu->cpsr.priv = MODE_UNDEFINED;
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
cpu->gprs[ARM_PC] = BASE_UNDEF; cpu->gprs[ARM_PC] = BASE_UNDEF;
int currentCycles = 0;
ARM_WRITE_PC;
_ARMSetMode(cpu, MODE_ARM); _ARMSetMode(cpu, MODE_ARM);
cpu->cycles += ARMWritePC(cpu);
cpu->spsr = cpsr; cpu->spsr = cpsr;
cpu->cpsr.i = 1; cpu->cpsr.i = 1;
cpu->cycles += currentCycles;
} }
static inline void ARMStep(struct ARMCore* cpu) { static inline void ARMStep(struct ARMCore* cpu) {

View File

@ -347,11 +347,10 @@ bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32
} }
if (strcmp(name, "pc") == 0) { if (strcmp(name, "pc") == 0) {
cpu->gprs[ARM_PC] = value; cpu->gprs[ARM_PC] = value;
int32_t currentCycles = 0;
if (cpu->executionMode == MODE_ARM) { if (cpu->executionMode == MODE_ARM) {
ARM_WRITE_PC; ARMWritePC(cpu);
} else { } else {
THUMB_WRITE_PC; ThumbWritePC(cpu);
} }
return true; return true;
} }
@ -363,11 +362,10 @@ bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32
} }
cpu->gprs[reg] = value; cpu->gprs[reg] = value;
if (reg == ARM_PC) { if (reg == ARM_PC) {
int32_t currentCycles = 0;
if (cpu->executionMode == MODE_ARM) { if (cpu->executionMode == MODE_ARM) {
ARM_WRITE_PC; ARMWritePC(cpu);
} else { } else {
THUMB_WRITE_PC; ThumbWritePC(cpu);
} }
} }
return true; return true;

View File

@ -253,7 +253,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
#define ADDR_MODE_2_WRITEBACK(ADDR) \ #define ADDR_MODE_2_WRITEBACK(ADDR) \
cpu->gprs[rn] = ADDR; \ cpu->gprs[rn] = ADDR; \
if (UNLIKELY(rn == ARM_PC)) { \ if (UNLIKELY(rn == ARM_PC)) { \
ARM_WRITE_PC; \ currentCycles += ARMWritePC(cpu); \
} }
#define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I) #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 \ #define ARM_LOAD_POST_BODY \
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; \ currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; \
if (rd == ARM_PC) { \ if (rd == ARM_PC) { \
ARM_WRITE_PC; \ currentCycles += ARMWritePC(cpu); \
} }
#define ARM_STORE_POST_BODY \ #define ARM_STORE_POST_BODY \
@ -301,9 +301,9 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
S_BODY; \ S_BODY; \
if (rd == ARM_PC) { \ if (rd == ARM_PC) { \
if (cpu->executionMode == MODE_ARM) { \ if (cpu->executionMode == MODE_ARM) { \
ARM_WRITE_PC; \ currentCycles += ARMWritePC(cpu); \
} else { \ } else { \
THUMB_WRITE_PC; \ currentCycles += ThumbWritePC(cpu); \
} \ } \
}) })
@ -594,7 +594,7 @@ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM,
load, load,
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32;
if (rs & 0x8000) { if (rs & 0x8000) {
ARM_WRITE_PC; currentCycles += ARMWritePC(cpu);
}) })
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM, DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM,
@ -625,22 +625,22 @@ DEFINE_INSTRUCTION_ARM(B,
int32_t offset = opcode << 8; int32_t offset = opcode << 8;
offset >>= 6; offset >>= 6;
cpu->gprs[ARM_PC] += offset; cpu->gprs[ARM_PC] += offset;
ARM_WRITE_PC;) currentCycles += ARMWritePC(cpu);)
DEFINE_INSTRUCTION_ARM(BL, DEFINE_INSTRUCTION_ARM(BL,
int32_t immediate = (opcode & 0x00FFFFFF) << 8; int32_t immediate = (opcode & 0x00FFFFFF) << 8;
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - WORD_SIZE_ARM; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - WORD_SIZE_ARM;
cpu->gprs[ARM_PC] += immediate >> 6; cpu->gprs[ARM_PC] += immediate >> 6;
ARM_WRITE_PC;) currentCycles += ARMWritePC(cpu);)
DEFINE_INSTRUCTION_ARM(BX, DEFINE_INSTRUCTION_ARM(BX,
int rm = opcode & 0x0000000F; int rm = opcode & 0x0000000F;
_ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001); _ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001);
cpu->gprs[ARM_PC] = cpu->gprs[rm] & 0xFFFFFFFE; cpu->gprs[ARM_PC] = cpu->gprs[rm] & 0xFFFFFFFE;
if (cpu->executionMode == MODE_THUMB) { if (cpu->executionMode == MODE_THUMB) {
THUMB_WRITE_PC; currentCycles += ThumbWritePC(cpu);
} else { } else {
ARM_WRITE_PC; currentCycles += ARMWritePC(cpu);
}) })
// End branch definitions // End branch definitions

View File

@ -238,14 +238,14 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(MVN, cpu->gprs[rd] = ~cpu->gprs[rn]; THUMB_
DEFINE_INSTRUCTION_WITH_HIGH_THUMB(ADD4, DEFINE_INSTRUCTION_WITH_HIGH_THUMB(ADD4,
cpu->gprs[rd] += cpu->gprs[rm]; cpu->gprs[rd] += cpu->gprs[rm];
if (rd == ARM_PC) { 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(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, DEFINE_INSTRUCTION_WITH_HIGH_THUMB(MOV3,
cpu->gprs[rd] = cpu->gprs[rm]; cpu->gprs[rd] = cpu->gprs[rm];
if (rd == ARM_PC) { if (rd == ARM_PC) {
THUMB_WRITE_PC; currentCycles += ThumbWritePC(cpu);
}) })
#define DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(NAME, BODY) \ #define DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(NAME, BODY) \
@ -310,7 +310,7 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(STMIA,
if (ARM_COND_ ## COND) { \ if (ARM_COND_ ## COND) { \
int8_t immediate = opcode; \ int8_t immediate = opcode; \
cpu->gprs[ARM_PC] += (int32_t) immediate << 1; \ cpu->gprs[ARM_PC] += (int32_t) immediate << 1; \
THUMB_WRITE_PC; \ currentCycles += ThumbWritePC(cpu); \
}) })
DEFINE_CONDITIONAL_BRANCH_THUMB(EQ) DEFINE_CONDITIONAL_BRANCH_THUMB(EQ)
@ -346,7 +346,7 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(POPR,
rs |= 1 << ARM_PC, rs |= 1 << ARM_PC,
THUMB_LOAD_POST_BODY; THUMB_LOAD_POST_BODY;
cpu->gprs[ARM_SP] = address; cpu->gprs[ARM_SP] = address;
THUMB_WRITE_PC;) currentCycles += ThumbWritePC(cpu);)
DEFINE_LOAD_STORE_MULTIPLE_THUMB(PUSH, DEFINE_LOAD_STORE_MULTIPLE_THUMB(PUSH,
ARM_SP, ARM_SP,
@ -369,7 +369,7 @@ DEFINE_INSTRUCTION_THUMB(BKPT, cpu->irqh.bkpt16(cpu, opcode & 0xFF);)
DEFINE_INSTRUCTION_THUMB(B, DEFINE_INSTRUCTION_THUMB(B,
int16_t immediate = (opcode & 0x07FF) << 5; int16_t immediate = (opcode & 0x07FF) << 5;
cpu->gprs[ARM_PC] += (((int32_t) immediate) >> 4); cpu->gprs[ARM_PC] += (((int32_t) immediate) >> 4);
THUMB_WRITE_PC;) currentCycles += ThumbWritePC(cpu);)
DEFINE_INSTRUCTION_THUMB(BL1, DEFINE_INSTRUCTION_THUMB(BL1,
int16_t immediate = (opcode & 0x07FF) << 5; int16_t immediate = (opcode & 0x07FF) << 5;
@ -380,7 +380,7 @@ DEFINE_INSTRUCTION_THUMB(BL2,
uint32_t pc = cpu->gprs[ARM_PC]; uint32_t pc = cpu->gprs[ARM_PC];
cpu->gprs[ARM_PC] = cpu->gprs[ARM_LR] + immediate; cpu->gprs[ARM_PC] = cpu->gprs[ARM_LR] + immediate;
cpu->gprs[ARM_LR] = pc - 1; cpu->gprs[ARM_LR] = pc - 1;
THUMB_WRITE_PC;) currentCycles += ThumbWritePC(cpu);)
DEFINE_INSTRUCTION_THUMB(BX, DEFINE_INSTRUCTION_THUMB(BX,
int rm = (opcode >> 3) & 0xF; int rm = (opcode >> 3) & 0xF;
@ -391,9 +391,9 @@ DEFINE_INSTRUCTION_THUMB(BX,
} }
cpu->gprs[ARM_PC] = (cpu->gprs[rm] & 0xFFFFFFFE) - misalign; cpu->gprs[ARM_PC] = (cpu->gprs[rm] & 0xFFFFFFFE) - misalign;
if (cpu->executionMode == MODE_THUMB) { if (cpu->executionMode == MODE_THUMB) {
THUMB_WRITE_PC; currentCycles += ThumbWritePC(cpu);
} else { } else {
ARM_WRITE_PC; currentCycles += ARMWritePC(cpu);
}) })
DEFINE_INSTRUCTION_THUMB(SWI, cpu->irqh.swi16(cpu, opcode & 0xFF)) DEFINE_INSTRUCTION_THUMB(SWI, cpu->irqh.swi16(cpu, opcode & 0xFF))

View File

@ -305,11 +305,10 @@ static void _writeGPRs(struct GDBStub* stub, const char* message) {
cpu->gprs[r] = _hex2int(readAddress, 8); cpu->gprs[r] = _hex2int(readAddress, 8);
readAddress += 8; readAddress += 8;
} }
int32_t currentCycles = 0;
if (cpu->executionMode == MODE_ARM) { if (cpu->executionMode == MODE_ARM) {
ARM_WRITE_PC; ARMWritePC(cpu);
} else { } else {
THUMB_WRITE_PC; ThumbWritePC(cpu);
} }
strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4); 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) { if (reg <= ARM_PC) {
cpu->gprs[reg] = value; cpu->gprs[reg] = value;
if (reg == ARM_PC) { if (reg == ARM_PC) {
int32_t currentCycles = 0;
if (cpu->executionMode == MODE_ARM) { if (cpu->executionMode == MODE_ARM) {
ARM_WRITE_PC; ARMWritePC(cpu);
} else { } else {
THUMB_WRITE_PC; ThumbWritePC(cpu);
} }
} }
} else if (reg == 0x19) { } else if (reg == 0x19) {

View File

@ -43,8 +43,7 @@ static void _SoftReset(struct GBA* gba) {
cpu->gprs[ARM_PC] = BASE_CART0; cpu->gprs[ARM_PC] = BASE_CART0;
} }
_ARMSetMode(cpu, MODE_ARM); _ARMSetMode(cpu, MODE_ARM);
int currentCycles = 0; ARMWritePC(cpu);
ARM_WRITE_PC;
} }
static void _RegisterRamReset(struct GBA* gba) { static void _RegisterRamReset(struct GBA* gba) {

View File

@ -242,8 +242,7 @@ void GBASkipBIOS(struct GBA* gba) {
} }
gba->memory.io[REG_VCOUNT >> 1] = 0x7E; gba->memory.io[REG_VCOUNT >> 1] = 0x7E;
gba->memory.io[REG_POSTFLG >> 1] = 1; gba->memory.io[REG_POSTFLG >> 1] = 1;
int currentCycles = 0; ARMWritePC(cpu);
ARM_WRITE_PC;
} }
} }