mirror of https://github.com/mgba-emu/mgba.git
Inline CPU stepping
This commit is contained in:
parent
f8de62ba71
commit
52808da265
119
src/arm/arm.c
119
src/arm/arm.c
|
@ -155,6 +155,125 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
|
|||
cpu->cpsr.i = 1;
|
||||
}
|
||||
|
||||
static inline ARMInstruction _ARMLoadInstructionARM(struct ARMMemory* memory, uint32_t address, uint32_t* opcodeOut) {
|
||||
uint32_t opcode;
|
||||
LOAD_32(opcode, address & memory->activeMask, memory->activeRegion);
|
||||
*opcodeOut = opcode;
|
||||
return _armTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
|
||||
}
|
||||
|
||||
static inline void ARMStep(struct ARMCore* cpu) {
|
||||
uint32_t opcode;
|
||||
cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_ARM;
|
||||
ARMInstruction instruction = _ARMLoadInstructionARM(cpu->memory, cpu->currentPC, &opcode);
|
||||
cpu->gprs[ARM_PC] += WORD_SIZE_ARM;
|
||||
|
||||
int condition = opcode >> 28;
|
||||
if (condition == 0xE) {
|
||||
instruction(cpu, opcode);
|
||||
return;
|
||||
} else {
|
||||
switch (condition) {
|
||||
case 0x0:
|
||||
if (!ARM_COND_EQ) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x1:
|
||||
if (!ARM_COND_NE) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x2:
|
||||
if (!ARM_COND_CS) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
if (!ARM_COND_CC) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x4:
|
||||
if (!ARM_COND_MI) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x5:
|
||||
if (!ARM_COND_PL) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x6:
|
||||
if (!ARM_COND_VS) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x7:
|
||||
if (!ARM_COND_VC) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x8:
|
||||
if (!ARM_COND_HI) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x9:
|
||||
if (!ARM_COND_LS) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xA:
|
||||
if (!ARM_COND_GE) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xB:
|
||||
if (!ARM_COND_LT) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xC:
|
||||
if (!ARM_COND_GT) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xD:
|
||||
if (!ARM_COND_LE) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
instruction(cpu, opcode);
|
||||
}
|
||||
|
||||
static inline void ThumbStep(struct ARMCore* cpu) {
|
||||
cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_THUMB;
|
||||
cpu->gprs[ARM_PC] += WORD_SIZE_THUMB;
|
||||
uint16_t opcode;
|
||||
LOAD_16(opcode, cpu->currentPC & cpu->memory->activeMask, cpu->memory->activeRegion);
|
||||
ThumbInstruction instruction = _thumbTable[opcode >> 6];
|
||||
instruction(cpu, opcode);
|
||||
}
|
||||
|
||||
void ARMRun(struct ARMCore* cpu) {
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
ThumbStep(cpu);
|
||||
|
|
|
@ -9,8 +9,6 @@ enum {
|
|||
PSR_STATE_MASK = 0x00000020
|
||||
};
|
||||
|
||||
#define ARM_PREFETCH_CYCLES (1 + cpu->memory->activePrefetchCycles32)
|
||||
|
||||
// Addressing mode 1
|
||||
static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
|
||||
int rm = opcode & 0x0000000F;
|
||||
|
@ -183,119 +181,6 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
}
|
||||
}
|
||||
|
||||
static const ARMInstruction _armTable[0x1000];
|
||||
|
||||
static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory* memory, uint32_t address, uint32_t* opcodeOut) {
|
||||
uint32_t opcode;
|
||||
LOAD_32(opcode, address & memory->activeMask, memory->activeRegion);
|
||||
*opcodeOut = opcode;
|
||||
return _armTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
|
||||
}
|
||||
|
||||
void ARMStep(struct ARMCore* cpu) {
|
||||
// TODO
|
||||
uint32_t opcode;
|
||||
cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_ARM;
|
||||
ARMInstruction instruction = _ARMLoadInstructionARM(cpu->memory, cpu->currentPC, &opcode);
|
||||
cpu->gprs[ARM_PC] += WORD_SIZE_ARM;
|
||||
|
||||
int condition = opcode >> 28;
|
||||
if (condition == 0xE) {
|
||||
instruction(cpu, opcode);
|
||||
return;
|
||||
} else {
|
||||
switch (condition) {
|
||||
case 0x0:
|
||||
if (!ARM_COND_EQ) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x1:
|
||||
if (!ARM_COND_NE) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x2:
|
||||
if (!ARM_COND_CS) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
if (!ARM_COND_CC) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x4:
|
||||
if (!ARM_COND_MI) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x5:
|
||||
if (!ARM_COND_PL) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x6:
|
||||
if (!ARM_COND_VS) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x7:
|
||||
if (!ARM_COND_VC) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x8:
|
||||
if (!ARM_COND_HI) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x9:
|
||||
if (!ARM_COND_LS) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xA:
|
||||
if (!ARM_COND_GE) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xB:
|
||||
if (!ARM_COND_LT) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xC:
|
||||
if (!ARM_COND_GT) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xD:
|
||||
if (!ARM_COND_LE) {
|
||||
cpu->cycles += ARM_PREFETCH_CYCLES;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
instruction(cpu, opcode);
|
||||
}
|
||||
|
||||
// Instruction definitions
|
||||
// Beware pre-processor antics
|
||||
|
||||
|
@ -1141,6 +1026,6 @@ DEFINE_INSTRUCTION_ARM(SWI, cpu->board->swi32(cpu->board, opcode & 0xFFFFFF))
|
|||
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC), \
|
||||
DECLARE_ARM_SWI_BLOCK(EMITTER)
|
||||
|
||||
static const ARMInstruction _armTable[0x1000] = {
|
||||
const ARMInstruction _armTable[0x1000] = {
|
||||
DECLARE_ARM_EMITTER_BLOCK(_ARMInstruction)
|
||||
};
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ARM_PREFETCH_CYCLES (1 + cpu->memory->activePrefetchCycles32)
|
||||
|
||||
struct ARMCore;
|
||||
|
||||
void ARMStep(struct ARMCore* cpu);
|
||||
typedef void (*ARMInstruction)(struct ARMCore*, uint32_t opcode);
|
||||
const ARMInstruction _armTable[0x1000];
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,17 +2,6 @@
|
|||
|
||||
#include "isa-inlines.h"
|
||||
|
||||
static const ThumbInstruction _thumbTable[0x400];
|
||||
|
||||
void ThumbStep(struct ARMCore* cpu) {
|
||||
cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_THUMB;
|
||||
cpu->gprs[ARM_PC] += WORD_SIZE_THUMB;
|
||||
uint16_t opcode;
|
||||
LOAD_16(opcode, cpu->currentPC & cpu->memory->activeMask, cpu->memory->activeRegion);
|
||||
ThumbInstruction instruction = _thumbTable[opcode >> 6];
|
||||
instruction(cpu, opcode);
|
||||
}
|
||||
|
||||
// Instruction definitions
|
||||
// Beware pre-processor insanity
|
||||
|
||||
|
@ -591,6 +580,6 @@ DEFINE_INSTRUCTION_THUMB(SWI, cpu->board->swi16(cpu->board, opcode & 0xFF))
|
|||
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL1))), \
|
||||
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL2)))
|
||||
|
||||
static const ThumbInstruction _thumbTable[0x400] = {
|
||||
const ThumbInstruction _thumbTable[0x400] = {
|
||||
DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction)
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
struct ARMCore;
|
||||
|
||||
void ThumbStep(struct ARMCore* cpu);
|
||||
typedef void (*ThumbInstruction)(struct ARMCore*, uint16_t opcode);
|
||||
const ThumbInstruction _thumbTable[0x400];
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue