mirror of https://github.com/mgba-emu/mgba.git
ARM: De-macro-ize ARM/Thumb PC write routines
This commit is contained in:
parent
830cad3e7b
commit
4d383b129d
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue