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_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;

View File

@ -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) {

View File

@ -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;

View File

@ -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

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,
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))

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
}
}