Inline CPU stepping
Jeffrey Pfau jeffrey@endrift.com
Tue, 21 Jan 2014 21:42:21 -0800
5 files changed,
126 insertions(+),
130 deletions(-)
M
src/arm/arm.c
→
src/arm/arm.c
@@ -155,6 +155,125 @@ cpu->spsr = cpsr;
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);
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -9,8 +9,6 @@ PSR_PRIV_MASK = 0x000000CF,
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;@@ -181,119 +179,6 @@ } else {
cpu->shifterOperand = ARM_ROR(immediate, rotate); cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand); } -} - -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@@ -1141,6 +1026,6 @@ DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \
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) };
M
src/arm/isa-arm.h
→
src/arm/isa-arm.h
@@ -3,9 +3,12 @@ #define ISA_ARM_H
#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
M
src/arm/isa-thumb.c
→
src/arm/isa-thumb.c
@@ -2,17 +2,6 @@ #include "isa-thumb.h"
#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 @@ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL))), \
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) };
M
src/arm/isa-thumb.h
→
src/arm/isa-thumb.h
@@ -5,7 +5,7 @@ #include <stdint.h>
struct ARMCore; -void ThumbStep(struct ARMCore* cpu); typedef void (*ThumbInstruction)(struct ARMCore*, uint16_t opcode); +const ThumbInstruction _thumbTable[0x400]; #endif